package com.ifsaid.im.service.impl;

import com.ifsaid.im.config.EasemobImProperties;
import com.ifsaid.im.context.EasemobImToken;
import com.ifsaid.im.entity.UserEntity;
import com.ifsaid.im.exception.UserException;
import com.ifsaid.im.service.IEasemobImService;
import com.ifsaid.im.util.JsonUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.net.URI;
import java.util.HashMap;
import java.util.Map;

/**
 * @description: 环信 IM API
 * @author: Wang Chen Chen<932560435@qq.com>
 * @date: 2019/11/4 14:54
 */

@Slf4j
@Service
public class EasemobImServiceImpl implements IEasemobImService {

    @Autowired
    private EasemobImProperties props;

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private EasemobImToken easemobImToken;

    /**
     * @description: 拼接 URL
     * @author: Wang Chen Chen<932560435@qq.com>
     * @date: 2019/11/4 15:05
     */
    private StringBuilder getHttpUrl(String suffix) {
        return new StringBuilder("http://a1.easemob.com/")
                .append(props.getOrgName())
                .append("/")
                .append(props.getAppName())
                .append("/")
                .append(suffix);
    }

    @Override
    public void refreshToken() {
        String url = getHttpUrl("token").toString();
        var headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        var request = new HttpEntity<String>(
                JsonUtils.objectToJson(
                        Map.of(
                                "grant_type", "client_credentials",
                                "client_id", props.getClientId(),
                                "client_secret", props.getClientSecret()
                        )
                ),
                headers);
        var response = restTemplate.postForEntity(URI.create(url), request, HashMap.class);
        if (response.getStatusCodeValue() == 200) {
            HashMap map = response.getBody();
            String access_token = (String) map.get("access_token");
            String application = (String) map.get("application");
            Integer expires_in = (Integer) map.get("expires_in");
            easemobImToken.setValue(application, access_token, expires_in);
            log.info("EasemobImToken : {}", easemobImToken);
        }
    }

    @Override
    public UserEntity registered(UserEntity entity) throws UserException {
        String url = getHttpUrl("users").toString();

        // 判断 token 是否过期，如果过期了，会自动刷新
        easemobImToken.isExpired();

        var headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.setBearerAuth(easemobImToken.getAccessToken());
        var request = new HttpEntity<String>(
                JsonUtils.objectToJson(
                        Map.of("username", entity.getUsername(),
                                "password", entity.getPassword())
                ), headers);
        var response = restTemplate.postForEntity(URI.create(url), request, HashMap.class);
        if (response.getStatusCodeValue() == 200) {
            // 返回值200，表示创建 IM 用户成功
            log.info("UserEntity : {}", entity);
            return entity;
        } else if (response.getStatusCodeValue() == 401) {
            // 返回值401，表示未授权[无token、token错误、token过期]
            refreshToken();
            registered(entity);
        } else if (response.getStatusCodeValue() == 400) {
            // 返回值400，表示用户已存在、用户名或密码为空、用户名不合法
            throw new UserException(response.getStatusCodeValue(),
                    "用户名称已存在、用户名或密码为空、用户名不合法");
        }
        return null;
    }

    @Override
    public void addFriend(String myName, String friendName) throws UserException {
        String url = getHttpUrl("users")
                .append("/")
                .append(myName)
                .append("/contacts/users/")
                .append(friendName).toString();
        // 判断 token 是否过期，如果过期了，会自动刷新
        easemobImToken.isExpired();
        var headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.setBearerAuth(easemobImToken.getAccessToken());
        var request = new HttpEntity<String>(headers);
        var response = restTemplate.postForEntity(URI.create(url), request, HashMap.class);
        if (response.getStatusCodeValue() == 200) {
            // 返回值200，表示 添加好友成功
            log.info("response : {}", response.getBody());
        } else if (response.getStatusCodeValue() == 401) {
            // 返回值401，表示未授权[无token、token错误、token过期]
            refreshToken();
            addFriend(myName, friendName);
        } else if (response.getStatusCodeValue() == 404) {
            // 返回值400，表示用户已存在、用户名或密码为空、用户名不合法
            throw new UserException(response.getStatusCodeValue(),
                    "用户名不存在 或者 此用户已经是好友！");
        }
    }

    @Override
    public boolean changePassword(UserEntity entity) {
        return false;
    }

}
